package com.ruoyi.bearing.service.Impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.ruoyi.bearing.domain.BearingModel;
import com.ruoyi.bearing.domain.BearingSignal;
import com.ruoyi.bearing.mapper.BearingSignalMapper;
import com.ruoyi.bearing.service.IBearingSignalService;
import com.ruoyi.common.constant.FlaskDataConstants;
import com.ruoyi.common.constant.FlaskModelConstants;
import com.ruoyi.common.enums.FilteringType;
import com.ruoyi.common.exception.flask.FlaskException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.flask.HttpFlask;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;
import java.util.Base64.Encoder;
import     java.util.Base64.Decoder;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * 信号分析
 */
@Service
public class BearingSignalServiceImpl implements IBearingSignalService {
    @Autowired
    BearingSignalMapper bearingSignalMapper;
    /**
     * 信号分析
     */
    public String startBearingSignalAnalysis(MultipartFile file, BearingModel bearingModel) throws IOException, IllegalAccessException {
        BearingSignal bearingSignal = new BearingSignal();
        String picResult = "";
        // 请求动态路径
        String res = HttpFlask.sendGetFlask(FlaskModelConstants.Model_CSV_URL);
        if (!"".equals(res)) {
            JSONObject jsonObject = JSONObject.parseObject(res);
            String dir = (String) jsonObject.get("data");
            String csvName = FileUploadUtils.upload(dir, file);
            String csvFileName = csvName.split("csv/")[1];
            bearingModel.setFileName(csvFileName);
            String postParam = HttpFlask.getKeyAndValueString(bearingModel);
            // 进行信号分析
            String analysisRes = HttpFlask.sendPostFlask(FlaskDataConstants.Data_SIGNAL_URL, postParam);
            if (!"".equals(analysisRes)) {
                JSONObject analysisJsonObject = JSONObject.parseObject(analysisRes);
                JSONArray json = (JSONArray) analysisJsonObject.get("data");
                if (!"fileError".equals(json.get(0))) {
                    bearingSignal.setId(IdUtils.simpleUUID());
                    bearingSignal.setPic((String) json.get(0));
                    bearingSignal.setFft((String) json.get(1));
                    bearingSignal.setStft((String) json.get(2));
                    if (bearingModel.getFiltering() != null & !"".equals(bearingModel.getFiltering())) {
                        bearingSignal.setFilteringName(getFilteringName(bearingModel.getFiltering()));
                        bearingSignal.setFilteringPic((String) json.get(3));
                    }
                    bearingSignal.setCreateTime(DateUtils.getNowDate());
                    bearingSignalMapper.insertBearingSignal(bearingSignal);
                    picResult = "success";
                } else {
                    picResult = "fileError";
                }
                return picResult;
            }
        }
        return null;
    }

    /**
     * 查询
     */
    public List<BearingSignal> selectBearingSignal(BearingSignal bearingSignal) {
        return bearingSignalMapper.selectBearingSignalList(bearingSignal);
    }

    /**
     * 批量删除信号分析结果
     */
    public int deleteAnalysisResultByIds(String[] ids) {
        return bearingSignalMapper.deleteBearingSignalByIds(ids);
    }

    /**
     * 下载pdf信号分析结果
     */
    public void downloadAnalysisResult(HttpServletResponse response, BearingSignal bearingSignal) {
        try {
            String res = HttpFlask.sendGetFlask(FlaskDataConstants.Data_QUERY_URL);
            if (!"".equals(res)) {
                JSONObject jsonObject = JSONObject.parseObject(res);
                String dir = (String) jsonObject.get("data");
                // 设置响应头以指示浏览器下载文件
                response.setContentType("application/pdf");
                response.setHeader("Content-Disposition", "attachment; filename=example.pdf");
                // 创建一个新的 PDF 文档
                Document document = new Document(PageSize.A4);
                BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                Font font = new Font(baseFont, 12);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                PdfWriter.getInstance(document, out);
                document.open();
                // 向文档中添加内容
                Rectangle pageSize = document.getPageSize();
                document.addTitle("信号分析结果");
                Paragraph paragraph = new Paragraph("信号分析结果\n", font);
                paragraph.setIndentationLeft(pageSize.getWidth() / 4);
                document.add(paragraph);
                BearingSignal bs = bearingSignalMapper.selectBearingSignalById(bearingSignal.getId());
                String id = bs.getId();
                Image image1 = null;
                Image image2 = null;
                Image image3 = null;
                String analysis_dir = dir + "//" + id + "//";
                if (bs.getPic() != null) {
                    downloadImg(bs.getPic(), id, analysis_dir, "analysis");
                    image1 = Image.getInstance(analysis_dir + "//analysis.jpg");
                    image1.scaleToFit(pageSize.getWidth() / 2, pageSize.getHeight() / 2);
                    document.add(new Paragraph("时域分析结果", font));
                    document.add(image1);
                }
                if (bs.getFft() != null) {
                    downloadImg(bs.getFft(), id, analysis_dir, "analysis_fft");
                    image2 = Image.getInstance(analysis_dir + "//analysis_fft.jpg");
                    image2.scaleToFit(pageSize.getWidth() / 2, pageSize.getHeight() / 2);
                    document.add(new Paragraph("频域分析结果", font));
                    document.add(image2);
                }
                if (bs.getStft() != null) {
                    downloadImg(bs.getStft(), id, analysis_dir, "analysis_stft");
                    image3 = Image.getInstance(analysis_dir + "//analysis_stft.jpg");
                    image3.scaleToFit(pageSize.getWidth() / 2, pageSize.getHeight() / 2);
                    document.add(new Paragraph("时频域分析结果", font));
                    document.add(image3);
                }
                if (bs.getFilteringName() != null & bs.getFilteringPic() != null) {
                    downloadImg(bs.getFilteringPic(), id, analysis_dir, "analysis_filtering_" + getFilteringCode(bearingSignal.getFilteringName()));
                }
                File directory = new File(dir);
                if (directory.isDirectory()) {
                    String filteringLabel = "analysis_filtering_";
                    File[] files = directory.listFiles();
                    if (files != null && files.length == 4) {
                        for (File file : files) {
                            if (file.isFile() & file.getName().contains(filteringLabel)) {
                                bearingSignal.setFilteringName(file.getName().substring(19, 20));
                            }
                        }
                    }
                }
                if (bearingSignal.getFilteringName() != null) {
                    String filteringCode = getFilteringCode(bearingSignal.getFilteringName());
                    Image image4 = Image.getInstance(analysis_dir + "//analysis_filtering_" + filteringCode + ".jpg");
                    image4.scaleToFit(pageSize.getWidth() / 2, pageSize.getHeight() / 2);
                    document.add(new Paragraph(bearingSignal.getFilteringName() + "滤波结果", font));
                    document.add(image4);
                }
                // 关闭文档并将其作为字节流返回给前端
                document.close();
                deleteFiles(new File(analysis_dir));
                response.getOutputStream().write(out.toByteArray());
                response.getOutputStream().flush();
            } else {
                throw new FlaskException();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取滤波器代码
     */
    private String getFilteringCode(String type) {
        String filteringCode = "";
        if (type.equals(FilteringType.MovingAverage.getInfo())) {
            filteringCode = FilteringType.MovingAverage.getCode();
        }
        if (type.equals(FilteringType.DWT.getInfo())) {
            filteringCode = FilteringType.DWT.getCode();
        }
        if (type.equals(FilteringType.BEADS.getInfo())) {
            filteringCode = FilteringType.BEADS.getCode();
        }
        if (type.equals(FilteringType.KalmanFiltering.getInfo())) {
            filteringCode = FilteringType.KalmanFiltering.getCode();
        }
        return filteringCode;
    }

    /**
     * 获取滤波器名称
     */
    private String getFilteringName(String type) {
        String filteringCode = "";
        if (type.equals(FilteringType.MovingAverage.getCode())) {
            filteringCode = FilteringType.MovingAverage.getInfo();
        }
        if (type.equals(FilteringType.DWT.getCode())) {
            filteringCode = FilteringType.DWT.getInfo();
        }
        if (type.equals(FilteringType.BEADS.getCode())) {
            filteringCode = FilteringType.BEADS.getInfo();
        }
        if (type.equals(FilteringType.KalmanFiltering.getCode())) {
            filteringCode = FilteringType.KalmanFiltering.getInfo();
        }
        return filteringCode;
    }
    
    /**
     * 保存图像
     */
    private void downloadImg(String pic, String id, String dir, String name) throws IOException {
        //对字节数组字符串进行Base64解码并生成图片
        String savePath = dir;
        Decoder decoder = Base64.getDecoder();
        //Base64解码
        byte[] bpic = decoder.decode(pic);
        // 判断路径是否不存在，不存在就创建文件夹
        File fileDir = new File(savePath);
        if (!fileDir.exists() && !fileDir.isDirectory()) {
            fileDir.mkdirs();
        }
        // 生成一个空文件，自定义图片的名字
        File file = new File(savePath + "\\" + name + ".jpg");
        if (!file.exists()) {
            file.createNewFile();
        }
        //生成jpg图片
        OutputStream out = new FileOutputStream(file.getPath());
        out.write(bpic);
        out.flush();
        out.close();
    }

    private void deleteFiles(File directory) {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    deleteFiles(file);
                }
            }
        }
        directory.delete();
    }
    
    
    private byte[] getImageByte(String base64str, Decoder decoder) throws IOException {
        byte[] b = decoder.decode(base64str);
        for (int i = 0; i < b.length; ++i) {
            //调整异常数据
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        return b;
    }
}
